package by.amakarevich.dataaccess.Impl;

import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;

import org.hibernate.jpa.criteria.OrderImpl;
import org.springframework.stereotype.Repository;

import by.amakarevich.dataaccess.ShoppingCartInfoDao;
import by.amakarevich.datamodel.Product;
import by.amakarevich.datamodel.ShoppingCart;
import by.amakarevich.datamodel.ShoppingCartInfo;
import by.amakarevich.datamodel.ShoppingCartInfo_;

@Repository
public class ShoppingCartInfoDaoImpl extends
		AbstractDaoImpl<Long, ShoppingCartInfo> implements ShoppingCartInfoDao {
	protected ShoppingCartInfoDaoImpl() {
		super(ShoppingCartInfo.class);
	}

	@Override
	public List<ShoppingCartInfo> getAllShoppingCartInfo() {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<ShoppingCartInfo> criteria = cBuilder
				.createQuery(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> root = criteria.from(ShoppingCartInfo.class);

		criteria.select(root);

		TypedQuery<ShoppingCartInfo> query = getEm().createQuery(criteria);
		List<ShoppingCartInfo> results = query.getResultList();
		return results;
	}

	@Override
	public List<ShoppingCartInfo> getAllShoppingCartInfoByShoppingCart(
			SingularAttribute<ShoppingCartInfo, ?> attr, boolean ascending,
			int startRecord, int pageSize) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<ShoppingCartInfo> criteria = cBuilder
				.createQuery(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> root = criteria.from(ShoppingCartInfo.class);

		criteria.select(root);
		criteria.orderBy(new OrderImpl(root.get(attr), ascending));

		TypedQuery<ShoppingCartInfo> query = getEm().createQuery(criteria);
		query.setFirstResult(startRecord);
		query.setMaxResults(pageSize);

		List<ShoppingCartInfo> results = query.getResultList();
		return results;
	}

	@Override
	public void deleteShoppingCartInfo(Long id) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaDelete<ShoppingCartInfo> root = cBuilder
				.createCriteriaDelete(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> criteria = root.from(ShoppingCartInfo.class);

		root.where(cBuilder.equal(criteria.get(ShoppingCartInfo_.id), id));

		getEm().createQuery(root).executeUpdate();
	}

	@Override
	public ShoppingCartInfo getShoppingCartInfo(ShoppingCart shoppingCart,
			Product product) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<ShoppingCartInfo> root = cBuilder
				.createQuery(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> criteria = root.from(ShoppingCartInfo.class);

		root.select(criteria);

		root.where(cBuilder.and(cBuilder.equal(
				criteria.get(ShoppingCartInfo_.shoppingCart),
				shoppingCart.getId())), cBuilder.equal(
				criteria.get(ShoppingCartInfo_.product), product.getId()));

		TypedQuery<ShoppingCartInfo> query = getEm().createQuery(root);
		List<ShoppingCartInfo> results = query.getResultList();
		
		ShoppingCartInfo result;
		if(results.size()>0){
				result= results.get(0);
			}else{
				result =null;
			}
		return result;

	}

	@Override
	public List<ShoppingCartInfo> getAllByShoppingCart(ShoppingCart shoppingCart) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		CriteriaQuery<ShoppingCartInfo> criteria = cBuilder
				.createQuery(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> root = criteria.from(ShoppingCartInfo.class);

		criteria.select(root);
		root.fetch(ShoppingCartInfo_.shoppingCart);
		criteria.distinct(true);
		criteria.where(cBuilder.equal(root.get(ShoppingCartInfo_.shoppingCart),
				shoppingCart.getId()));

		TypedQuery<ShoppingCartInfo> query = getEm().createQuery(criteria);
		List<ShoppingCartInfo> results = query.getResultList();
		return results;
	}

	@Override
	public ShoppingCartInfo getByShoppingCartId(Long shoppingCartInfoId) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		CriteriaQuery<ShoppingCartInfo> criteria = cBuilder
				.createQuery(ShoppingCartInfo.class);
		Root<ShoppingCartInfo> root = criteria.from(ShoppingCartInfo.class);

		criteria.select(root);
		root.fetch(ShoppingCartInfo_.product);
		criteria.distinct(true);
		criteria.where(cBuilder.equal(root.get(ShoppingCartInfo_.id),
				shoppingCartInfoId));

		TypedQuery<ShoppingCartInfo> query = getEm().createQuery(criteria);
		ShoppingCartInfo result = (ShoppingCartInfo) query.getSingleResult();
		return result;
	}

}
